"""
NetworkMakerPlayer.py

Author: Zach Epolito
Date: 10-04-08
"""

from NetworkWaitFrame import NetworkWaitFrame
from Game import Game
from threading import Thread
from UndoCommand import UndoCommand
from MoveCommand import MoveCommand
from WaitFrame import WaitFrame
import socket

"""represents a player on the network making a move"""
class NetworkMakerPlayer(Thread):

    """Constructor."""
    def __init__(self, game, host, gui, waitTime):
        Thread.__init__(self)
        
        self.game = game
        self.host = host
        self.gui = gui
        self.waitTime = waitTime
                
        game.register_observer(self)

        self.start()

    """Runs a thread waiting for input from
       the network breaker player"""
    def run(self):

        if self.host == "":
            #server
            #try:
            print "M1"
            server_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            server_sock.bind(('0.0.0.0', 1527))
            server_sock.listen(1)
            self.conn, info = server_sock.accept()
            
            #except e:
                #print e
        else:
            #client
            #try:
            print "M2"
            client_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            client_sock.connect((self.host, 1518))
            self.conn = client_sock
            #except e:
                #print e
          
        msg = None
        while 1:
            msg = self.conn.recv(1024)
            if (msg != None):
                self.handleSocket(msg)
                msg = None

    """Deciphers the string returned by the coket
       and handles related command"""
    def handleSocket(self, msg):
        #Display waiting in GUI
        frame = NetworkWaitFrame(self.gui.getRootInputView(), width=300, height=100)
        self.gui.set_input_view(frame)

        #Starts a new thread and waits for
        #the network player to make a move.
        """To be implemented"""
        self.input = msg.split(' ')
        #Determines what type of move the
        #network player made

        #A breaker move is ignored.
        if (self.input[0] == 'g'):
            self.startFunctor()
        
        #A maker move
        if (self.input[0] == 'f'):
            guess = [None,None,None,None]
            move = [None,None,None,None,None]
            move = self.input.split(' ')

            #loops index from 1-4
            for index in range(1, 5):
                if (move[index] == x):
                    self.guess[index-1] = 0
                if (move[index] == w):
                    self.guess[index-1] = 1
                if (move[index] == b):
                    self.guess[index-1] = 2

            self.makerMove = MakerMove(guess)

            if self.game.turn == self.game.MAKER_TURN :
                self.moveCommand.execute(makerMove)

        #Undo
        if (self.input[0] == 'u'):
            self.undoCommand.execute()

        #A winner has been declared
        if (self.input[0] == 'w'):
            self.winCommand.execute()

        #New game
        if (self.input[0] == 'n'):
            self.newGameCommand.execute()

        #Exit game
        if (self.input[0] == 'e'):
            self.closeCommand.execute()

    """Passes messages through the socket to the
       network player"""
    #Currently only passing moves and undo's are implemented
    def update(self, subject, param):
        
        if subject == game: 
            if param == Game.NOTIFY_MOVE:
                if self.game.turn == self.game.MAKER_TURN : 
                    frame = NetworkWaitFrame(gui.getRootInputView(),
                                                      width=300, height=100)
                    self.gui.set_input_view(frame)
                    self.sendCommand(get_last_move().get_network_string())
            elif param == Game.NOTIFY_UNDO:
                self.sendCommand('u')

    def sendCommand(self, msg):
        self.conn.send(msg)
        
    def setStartingCode(self, startFunctor):
        frame = NetworkWaitFrame(self.gui.getRootInputView(),
                                     width=300, height=100)
        self.gui.set_input_view(frame)
        self.startFunctor = startFunctor

    def setWaitTime(self, waitTime):
        self.waitTime = waitTime

    def setCommands(self, undoCommand, winCommand, moveCommand,
                    exitCommand, newGameCommand):
        self.moveCommand = moveCommand
        self.undoCommand = undoCommand
        self.winCommand = winCommand
        self.exitCommand = exitCommand
        self.newGameCommand = newGameCommand

    """handle if new game or exit command is executed"""
    def handleCommandExecuted(self, cmd):
        if cmd == 'exit':
            self.sendCommand('e')
        elif cmd == 'new':
            self.sendCommand('n')
